package com.iwechat.adapter.mina;

import java.nio.charset.Charset;

import javax.annotation.PostConstruct;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import org.apache.mina.proxy.utils.ByteUtilities;

import com.iwechat.adapter.mina.entity.Active;
import com.iwechat.adapter.mina.entity.ActiveResp;
import com.iwechat.adapter.mina.entity.Connect;
import com.iwechat.adapter.mina.entity.ConnectResp;
import com.iwechat.adapter.mina.entity.Exit;
import com.iwechat.adapter.mina.entity.ExitResp;
import com.iwechat.adapter.mina.entity.PDUHeader;
import com.iwechat.adapter.mina.entity.Submit;
import com.iwechat.adapter.mina.entity.SubmitResp;

public class NioProtocolEncoder extends ProtocolEncoderAdapter {
    private static final Logger logger = LogManager.getLogger();

    private String              charset;
    private String              preFix;
    private Charset             charSet;

    @PostConstruct
    public void initCoder() {
        this.charSet = Charset.forName(charset);
        logger.info("### " + this + " init succeed!");
    }

    @Override
    public void encode(IoSession ioSession, Object pdu, ProtocolEncoderOutput out) throws Exception {
        IoBuffer pre = IoBuffer.allocate(6);
        pre.put(preFix.getBytes(charSet));
        pre.flip();
        out.write(pre);
        out.flush();

        IoBuffer buffer = null;
        // Submit
        if (pdu instanceof Submit) {
            buffer = ((Submit) pdu).toIoBuffer(charSet);
        } else if (pdu instanceof SubmitResp) {
            buffer = ((SubmitResp) pdu).toIoBuffer(charSet);
        }
        // Connect
        else if (pdu instanceof Connect) {
            buffer = ((Connect) pdu).toIoBuffer(charSet);
        } else if (pdu instanceof ConnectResp) {
            buffer = ((ConnectResp) pdu).toIoBuffer(charSet);
        }
        // Active
        else if (pdu instanceof Active) {
            buffer = ((Active) pdu).toIoBuffer(charSet);
        } else if (pdu instanceof ActiveResp) {
            buffer = ((ActiveResp) pdu).toIoBuffer(charSet);
        }
        // Exit
        else if (pdu instanceof Exit) {
            buffer = ((Exit) pdu).toIoBuffer(charSet);
        } else if (pdu instanceof ExitResp) {
            buffer = ((ExitResp) pdu).toIoBuffer(charSet);
        }
        // other
        else {
            buffer = ((PDUHeader) pdu).toIoBuffer(charSet);
        }

        out.write(buffer);
        out.flush();

        if (logger.isDebugEnabled()) {
            logger.debug("sessionId[" + ioSession.getId() + "] send_data_hex:" + ByteUtilities.asHex(buffer.array()));
        }
    }

    public String getCharset() {
        return charset;
    }

    public void setCharset(String charset) {
        this.charset = charset;
    }

    public String getPreFix() {
        return preFix;
    }

    public void setPreFix(String preFix) {
        this.preFix = preFix;
    }

}
